package fr.inria.phoenix.scenario.bwsnfirefighting.framework.distributed.temperaturedetection;

import java.util.HashMap;

import fr.inria.diagen.core.ServiceConfiguration;
import fr.inria.diagen.core.exception.DiaGenException;
import fr.inria.diagen.core.exception.InvocationException;
import fr.inria.diagen.core.network.RemoteServiceInfo;
import fr.inria.diagen.core.service.local.Service;

import fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel;
import java.lang.Integer;
import fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.Location;

import fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.TemperatureDetectionDataType;
import fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.TemperatureDetectionIndices;
import fr.inria.diagen.core.service.proxy.Proxy;
import fr.inria.diagen.core.module.event.IEventNotifyListener;
import fr.inria.diagen.core.module.command.ICommandListener;
import fr.inria.diagen.core.server.local.EventSubscription;
import fr.inria.diagen.core.service.filter.service.ServiceFilter;
import fr.inria.diagen.core.exception.InvocationException;

/**
 * 
 *
 * @[89,0]
 * context TemperatureDetection as DangerLevel indexed by location as Location {
 * source temperature from EnvironmentSensorDevice;
 * }
 */
public abstract class TemperatureDetection extends Service implements IEventNotifyListener, ICommandListener {
  /**
     * @param serviceConfiguration
     */
    public TemperatureDetection(ServiceConfiguration serviceConfiguration ) {
      super("TemperatureDetection", serviceConfiguration, GeneratedFramework.getInstance());
    }

	protected final void _postInitialize() {
		postInitialize();
	}
	protected void postInitialize() {}


    private HashMap<TemperatureDetectionIndices,fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel> temperatureDetection = new HashMap<TemperatureDetectionIndices,fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel>();
    /**
     * @[89,0]
     * context TemperatureDetection as DangerLevel indexed by location as Location {
     * source temperature from EnvironmentSensorDevice;
     * }
     */  
    protected void setTemperatureDetection(fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel newTemperatureDetectionValue , fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.Location location) {
      TemperatureDetectionIndices _indices_ = new TemperatureDetectionIndices(location);
      temperatureDetection.put(_indices_,newTemperatureDetectionValue);
      getServer().publish("TemperatureDetection", new TemperatureDetectionDataType(newTemperatureDetectionValue, location)); 
    }

    /**
     * @[89,0]
     * context TemperatureDetection as DangerLevel indexed by location as Location {
     * source temperature from EnvironmentSensorDevice;
     * }
     */
    protected fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel getTemperatureDetection(fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.Location location) {
      return temperatureDetection.get(new TemperatureDetectionIndices(location));    }
    
    public final Object commandReceived(RemoteServiceInfo rsi, String methodName, Object... args) throws DiaGenException {
      if (methodName.equals("getTemperatureDetection"))
        return (fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel) getTemperatureDetection((fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.Location)args[0]);

      throw new InvocationException("Unsupported method call: " + methodName);
    }
    
    public void notifyReceived(RemoteServiceInfo servicePublisher, String eventName, Object arg) {
        try {
          if (eventName.equals("temperature") && servicePublisher.getClassName().equals("EnvironmentSensorDevice")) {
            onNewTemperature ((EnvironmentSensorDeviceProxy) createProxy(servicePublisher),(java.lang.Integer) arg);          }

        } catch (Exception e) {
              e.printStackTrace();
        }
    }

    public abstract void onNewTemperature(EnvironmentSensorDeviceProxy proxy,java.lang.Integer newTemperatureValue);
    
    public void subscribeTemperature(EnvironmentSensorDeviceProxy proxy) {
      getServer().subscribe(new EventSubscription(proxy.getRemoteServiceInfo(), getServiceInfo(), "temperature"), 3600);
    }
    

    protected final EnvironmentSensorDeviceComposite discover(EnvironmentSensorDeviceServiceFilter filter) {
      RemoteServiceInfo[] rsis = getServicesInfo(getServer(), filter);
      EnvironmentSensorDeviceProxy[] proxies = new EnvironmentSensorDeviceProxy[rsis.length];
      for (int i = 0; i < rsis.length; i++) {
        proxies[i] = new EnvironmentSensorDeviceProxy(getProcessor(), rsis[i]);
      }
      return new EnvironmentSensorDeviceComposite(proxies, this);
    }
    
    protected final EnvironmentSensorDeviceComposite allEnvironmentSensorDevices() {
        return discover(new EnvironmentSensorDeviceServiceFilter());
    }
    
    protected final EnvironmentSensorDeviceServiceFilter environmentSensorDevicesWhere() {
        return new EnvironmentSensorDeviceServiceFilter();
    }

}